package view.components;

import java.awt.Dimension;
import java.util.ArrayList;

import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import model.HostAddress;
import model.IPAddress;
import model.Subnet;
import view.listeners.TreeListener;
import controller.Controller;

public class NetworkTree extends JTree {
	private DefaultMutableTreeNode rootTreeNode;
	private DefaultTreeModel treeModel;
	private Controller controller;
	private IpAddressTable ipAddressTable;
	private static final long serialVersionUID = 1L;
	ArrayList<HostAddress> hostAddressList;
	private TreeListener listener;
	private DefaultMutableTreeNode selectedNode;

	public NetworkTree() {
		loadTree();
		this.setPreferredSize(new Dimension(160, 300));

	}

	public void addRow(String newAddress, String infoText) {
		selectedNode = getSelectedNode();
		errorMessage("Wählen Sie ein Host oder Subnetz aus.");

		if (selectedNode.getLevel() == 0) {
			newHostAdress(newAddress, infoText);
			treeModel.insertNodeInto(new DefaultMutableTreeNode(newAddress),
					selectedNode, selectedNode.getChildCount());
		}

		if (selectedNode.getLevel() == 1) {
			newSubnet(newAddress, infoText);
			treeModel.insertNodeInto(new DefaultMutableTreeNode(newAddress),
					selectedNode, selectedNode.getChildCount());
		}

	}

	/**
	 * @param newAddress
	 * @param infoText
	 */
	private void newSubnet(String newAddress, String infoText) {
		for (int i = 0; i < hostAddressList.size(); i++) {
			for (int y = 0; y < hostAddressList.get(i).getSubnetList().size(); y++) {
				if (hostAddressList.get(i).getSubnetList().get(y)
						.getNetAdress().getAddress() == selectedNode.toString()) {
					hostAddressList
							.get(i)
							.getSubnetList()
							.add(new Subnet(new IPAddress(newAddress), 10,
									infoText));
					controller.setHosts(hostAddressList);
				}
			}
		}
	}

	private void newHostAdress(String newAddress, String infoText) {
		hostAddressList
				.add(new HostAddress(new IPAddress(newAddress), infoText));
		controller.setHosts(hostAddressList);
	}

	public void removeRow() {
		selectedNode = getSelectedNode();
		errorMessage("Wählen Sie ein Host oder Subnetz aus.");
		if (selectedNode.getLevel() == 0) {
			errorMessage("Sämtliche Netzwerke löschen nicht möglich!");
		}
		if (selectedNode.getLevel() == 1) {
			removeHostAdress();
		}
		if (selectedNode.getLevel() == 2) {
			removeSubnet();
		}
	}

	private void removeSubnet() {
		for (int i = 0; i < hostAddressList.size(); i++) {
			for (int y = 0; y < hostAddressList.get(i).getSubnetList().size(); y++) {
				if (hostAddressList.get(i).getSubnetList().get(y)
						.getNetAdress().getAddress() == selectedNode.toString()) {
					hostAddressList.get(i).getSubnetList().remove(y);
					controller.setHosts(hostAddressList);
					treeModel.removeNodeFromParent(getSelectedNode());
				}
			}
		}
	}

	private void removeHostAdress() {
		for (int i = 0; i < hostAddressList.size(); i++) {
			if (hostAddressList.get(i).getHostAddress().getAddress() == selectedNode
					.toString()) {
				hostAddressList.remove(i);
				controller.setHosts(hostAddressList);
				treeModel.removeNodeFromParent(getSelectedNode());
			}
		}
	}

	public DefaultMutableTreeNode getSelectedNode() {
		return (DefaultMutableTreeNode) this.getLastSelectedPathComponent();
	}

	public void setIpAddressTable(IpAddressTable ipAddressTable) {
		this.ipAddressTable = ipAddressTable;
		listener.setTable(ipAddressTable);
	}

	private ArrayList<HostAddress> loadHostAdressList() {
		controller = Controller.getInstance();
		hostAddressList = controller.getHosts();
		return hostAddressList;
	}

	public void loadTree() {
		loadHostAdressList();
		loadTreeContent();
		this.setModel(treeModel);

		listener = new TreeListener();
		listener.setTree(this);
		this.addMouseListener(listener);

	}
	
	public Subnet getSubnetFromAddress(String ipAddress){
		ArrayList<HostAddress> hostArray = Controller.getInstance().getHosts();
		Subnet subnet = null;
		for(HostAddress host : hostArray){
			for (Subnet subnetItem :host.getSubnetList()){
				if (subnetItem.getNetAdress().getAddress().equals(ipAddress)){
					subnet = subnetItem;
				}
			}
		}
		return subnet;
		
	}
	
	public HostAddress getHostFromAddress(String ipAddress){
		ArrayList<HostAddress> hostArray = Controller.getInstance().getHosts();
		HostAddress host = null;
		for(HostAddress hostItem : hostArray){
			if (hostItem.getHostAddress().getAddress().equals(ipAddress)){
					host = hostItem;
				}
			}
		
		return host;
		
	}
	
	

	private DefaultTreeModel loadTreeContent() {
		rootTreeNode = new DefaultMutableTreeNode("Host-Adressen");

		for (int i = 0; i < hostAddressList.size(); i++) {
			DefaultMutableTreeNode hostTreeNode = new DefaultMutableTreeNode(
					hostAddressList.get(i).getHostAddress().getAddress());
			rootTreeNode.add(hostTreeNode);

			for (int y = 0; y < hostAddressList.get(i).getSubnetList().size(); y++) {
				DefaultMutableTreeNode subnetTreeNode = new DefaultMutableTreeNode(
						hostAddressList.get(i).getSubnetList().get(y)
								.getNetAdress().getAddress());
				hostTreeNode.add(subnetTreeNode);
			}
		}
		treeModel = new DefaultTreeModel(rootTreeNode);
		return treeModel;
	}

	private void errorMessage(String errorText) {
		if (selectedNode == null) {
			JOptionPane.showMessageDialog(NetworkTree.this, errorText, "Error",
					JOptionPane.ERROR_MESSAGE);

			return;
		}
	}

}
